﻿using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedGenomics.Domain;
using SharedGenomics.Workbench.Core;
using SharedGenomics.Workbench.Models;
using SharedGenomics.Workbench.Services;

using Rhino.Mocks;
using Rhino.Mocks.Constraints;

namespace SharedGenomics.Workbench.Tests.Models
{
    [TestClass]
    public class AnalysisResultsRepositoryTests
    {
        private MockRepository mocks;
        private IAnalysisResultsLocator locator;
        private AnalysisResultsFileParser parser;
        private IAnalysisResultsFileReadStrategy readStrategy;
        private AnalysisResultsRepository repository;

        [TestInitialize]
        public void Setup()
        {
            this.mocks = new MockRepository();
            this.locator = this.mocks.Stub<IAnalysisResultsLocator>();
            this.parser = this.mocks.Stub<AnalysisResultsFileParser>();
            this.readStrategy = this.mocks.Stub<IAnalysisResultsFileReadStrategy>();

            this.repository = new AnalysisResultsRepository(this.locator, this.parser, this.readStrategy);
        }

        [TestMethod]
        public void ShouldGetResultsSet()
        {
            IAnalysisResultSet resultSet = this.mocks.Stub<IAnalysisResultSet>();

            using (this.mocks.Record())
            {
                AnalysisResultsInfo info = new AnalysisResultsInfo(JobType.PassocBT, new MemoryStream());

                this.locator.Stub(l => l.FindResultsForJob(1)).Return(info.Just());
                this.parser.Expect(p => p.ParseResultsFile(null, JobType.PassocBT, null))
                    .IgnoreArguments()
                    .Constraints(Is.Anything(), Is.Equal(JobType.PassocBT), Is.Equal(this.readStrategy))
                    .Return(resultSet);
            }

            using (this.mocks.Playback())
            {
                var resultMaybe = this.repository.GetResultsForJob(1);
                Assert.AreEqual(resultSet, resultMaybe.Value);
            }
        }

        [TestMethod]
        public void ShouldReturnNothing()
        {
            using (this.mocks.Record())
            {
                this.locator.Stub(l => l.FindResultsForJob(1)).Return(new Maybe<AnalysisResultsInfo>());
            }

            using (this.mocks.Playback())
            {
                var resultSetMaybe = this.repository.GetResultsForJob(1);
                Assert.IsFalse(resultSetMaybe.HasValue, "Result set has value");
            }
        }
    }
}
